#pragma once

#include "mayaincludes.h"
#include <string>
#include <map>
#include <set>
#include <vector>

class MayaArgParser
{
private:
	std::string cmdName;

	// flag parser are defined below.
	class FlagParser;

	std::map<std::string,FlagParser*> flags;
	typedef std::map<std::string,FlagParser*>::iterator FlagIt;
	typedef std::map<std::string,FlagParser*>::const_iterator ConstFlagIt;

	bool parseNodeArgs;
	int minNNodes;
	int maxNNodes;
	bool useSelectionAsDefault;
	std::vector<MDagPath> nodesArg;

public:
	MayaArgParser(const std::string &cmdName);
	~MayaArgParser();

	const std::string& GetCommandName() const
	{
		return cmdName;
	}

	enum FlagType
	{
		FLAG,
		STRING,
	};
	void AddFlag(std::string shortName,std::string longName,FlagType flagType);
	void SetNodeArgHandling(int minNNodes,int maxNNodes,bool useSelectionAsDefault);
	const std::vector<MDagPath> GetNodeArgs() const;

	void Parse(const MArgList &args);

	bool IsFlagSet(std::string name) const;
	const std::string& GetFlagString(std::string name) const;

private:
	class FlagParser
	{
	private:
		std::string shortName;
		std::string longName;

		bool isSet;

	public:
		FlagParser(const std::string &shortName,const std::string &longName)
			: shortName(shortName),longName(longName)
		{
			isSet = false;
		}

		virtual ~FlagParser()
		{
		}

		const std::string& GetShortName() const
		{
			return shortName;
		}

		const std::string& GetLongName() const
		{
			return longName;
		}

		virtual FlagType GetFlagType() const = 0;

		void SetIsSet(bool value)
		{
			isSet = value;
		}

		bool IsSet() const
		{
			return isSet;
		}


		virtual void Parse(const MArgList &argList,int &index,MayaArgParser *pArgParser) = 0;
	};

	class ParamlessFlagParser : public FlagParser
	{
	public:
		ParamlessFlagParser(const std::string &shortName,const std::string &longName)
			: FlagParser(shortName,longName)
		{
		}

		virtual FlagType GetFlagType() const
		{
			return FLAG;
		}

		virtual void Parse(const MArgList &argList,int &index,MayaArgParser *pArgParser)
		{
			// nothing
		}
	};

	class StringFlagParser : public FlagParser
	{
	private:
		bool specified;
		std::string value;

	public:
		StringFlagParser(const std::string &shortName,const std::string &longName);

		virtual FlagType GetFlagType() const
		{
			return STRING;
		}

		virtual void Parse(const MArgList &argList,int &index,MayaArgParser *pArgParser);

		const std::string& GetValue() const
		{
			return value;
		}
	};
};